<template>
  <div ref="waterfallWrapper" class="waterfall-list" :style="{ height: `${wrapperHeight}px` }">
    <div v-for="(item, index) in list" :key="getKey(item, index)" class="waterfall-item">
      <slot name="item" :item="item" :index="index" :url="getRenderURL(item)" />
    </div>
  </div>
</template>

<script>
import { ref, computed, watch, onMounted, provide, getCurrentInstance, onBeforeUnmount } from "vue";

// 简化的防抖函数
function useDebounceFn(fn, ms = 200) {
  let timer = null;
  return (...args) => {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, args);
      timer = null;
    }, ms);
  };
}

export default {
  props: {
    list: {
      type: Array,
      default: () => []
    },
    rowKey: {
      type: String,
      default: "id"
    },
    imgSelector: {
      type: String,
      default: "src"
    },
    width: {
      type: Number,
      default: 200
    },
    breakpoints: {
      type: Object,
      default: () => ({
        1200: { rowPerView: 4 },
        800: { rowPerView: 3 },
        500: { rowPerView: 2 }
      })
    },
    gutter: {
      type: Number,
      default: 10
    },
    hasAroundGutter: {
      type: Boolean,
      default: true
    },
    posDuration: {
      type: Number,
      default: 300
    },
    align: {
      type: String,
      default: "center",
      validator: (value) => ['left', 'center', 'right'].includes(value)
    },
    horizontalOrder: {
      type: Boolean,
      default: false
    },
    // 新增懒加载相关props
    lazyLoad: {
      type: Boolean,
      default: true
    },
    crossOrigin: {
      type: Boolean,
      default: true
    },
    delay: {
      type: Number,
      default: 300
    },
    loadingImg: {
      type: String,
      default: ''
    },
    errorImg: {
      type: String,
      default: ''
    }
  },

  setup(props, { emit }) {
    const waterfallWrapper = ref(null);
    const wrapperWidth = ref(0);
    const colWidth = ref(0);
    const cols = ref(0);
    const offsetX = ref(0);
    const wrapperHeight = ref(0);
    const positions = ref([]);
    const observer = ref(null); // IntersectionObserver实例
    const targetElement = ref(null);


    // 计算列数
    const calculateColumns = () => {
      if (!waterfallWrapper.value) return;
      wrapperWidth.value = waterfallWrapper.value.clientWidth;
      const sizeList = Object.keys(props.breakpoints).map(Number).sort((a, b) => a - b);
      let validSize = wrapperWidth.value;
      for (const size of sizeList) {
        if (wrapperWidth.value <= size) {
          validSize = size;
          break;
        }
      }
      cols.value = props.breakpoints[validSize]?.rowPerView || 1;
      if (props.hasAroundGutter) {
        colWidth.value = (wrapperWidth.value - props.gutter * 2 - (cols.value - 1) * props.gutter) / cols.value;
        offsetX.value = props.gutter;
      } else {
        colWidth.value = (wrapperWidth.value - (cols.value - 1) * props.gutter) / cols.value;
        offsetX.value = 0;
      }
    };

    // 布局计算逻辑
    const calculateLayout = () => {
      if (cols.value === 0 || !waterfallWrapper.value) return;

      const columnHeights = new Array(cols.value).fill(0);
      positions.value = [];
      const items = Array.from(waterfallWrapper.value.querySelectorAll('.waterfall-item'));

      items.forEach((item, index) => {
        let minHeight = columnHeights[0];
        let colIndex = 0;

        for (let i = 1; i < cols.value; i++) {
          if (columnHeights[i] < minHeight) {
            minHeight = columnHeights[i];
            colIndex = i;
          }
        }

        const x = colIndex * (colWidth.value + props.gutter) + offsetX.value;
        const y = columnHeights[colIndex];

        item.style.transform = `translate3d(${x}px, ${y}px, 0)`;
        item.style.width = `${colWidth.value}px`;
        item.style.visibility = 'visible';

        const height = item.clientHeight || 200;
        columnHeights[colIndex] += height + props.gutter;
      });

      wrapperHeight.value = Math.max(...columnHeights);
      emit('afterRender');
    };

    const debouncedLayout = useDebounceFn(() => {
      calculateColumns();
      calculateLayout();
    }, props.posDuration);

    // 初始化懒加载观察器
    const initLazyLoadObserver = () => {
      if (!props.lazyLoad || !waterfallWrapper.value) return;

      // 如果已有观察器，先断开之前的
      if (observer.value) {
        observer.value.disconnect();
      }

      // 创建新的IntersectionObserver
      observer.value = new IntersectionObserver((entries) => {
        entries.forEach(entry => {
          if (entry.isIntersecting) {
            const img = entry.target;
            if (img.dataset.src) {
              // 加载图片
              img.src = img.dataset.src;
              if (props.crossOrigin) {
                img.crossOrigin = 'anonymous';
              }

              // 图片加载完成后刷新布局
              img.onload = () => {
                debouncedLayout();
              };

              // 图片加载错误处理
              img.onerror = () => {
                if (props.errorImg) {
                  img.src = props.errorImg;
                }
              };

              // 移除data-src属性，避免重复加载
              img.removeAttribute('data-src');
            }
            // 停止观察该元素
            observer.value.unobserve(img);
          }
        });
      }, {
        root: null,
        rootMargin: '0px',
        threshold: 0.1
      });

      // 观察所有需要懒加载的图片
      const lazyImages = waterfallWrapper.value.querySelectorAll('img[data-src]');
      lazyImages.forEach(img => {
        observer.value.observe(img);
      });
    };

    // 处理图片懒加载
    const handleLazyLoad = () => {
      if (!props.lazyLoad) return;

      // 设置占位图
      if (props.loadingImg) {
        const images = waterfallWrapper.value.querySelectorAll('img[data-src]');
        images.forEach(img => {
          img.src = props.loadingImg;
        });
      }

      // 初始化观察器
      initLazyLoadObserver();
    };

    // 初始化
    onMounted(() => {
      // 初始计算
      setTimeout(() => {
        calculateColumns();
        calculateLayout();

        // 初始化懒加载
        if (props.lazyLoad) {
          handleLazyLoad();
        }
      }, 100);

      // 窗口大小变化监听
      window.addEventListener('resize', debouncedLayout);
    });

    // 列表变化监听
    watch(() => props.list, () => {
      debouncedLayout();
      if (props.lazyLoad) {
        // 延迟执行以确保DOM已更新
        setTimeout(() => {
          handleLazyLoad();
        }, props.delay);
      }
    }, { deep: true });

    // 清理观察器
    onMounted(() => {
      // 创建 IntersectionObserver
      observer.value = new IntersectionObserver((entries) => {
        // 观察者逻辑
      });

      if (targetElement.value) {
        observer.value.observe(targetElement.value);
      }
    });
    onBeforeUnmount(() => {
      // 组件卸载前清理观察者
      if (observer.value) {
        observer.value.disconnect();
      }
    });
    // 提供布局刷新方法给子组件
    provide('refreshLayout', debouncedLayout);

    const getRenderURL = (item) => {
      return item[props.imgSelector];
    };

    const getKey = (item, index) => {
      return item[props.rowKey] || index;
    };

    return {
      waterfallWrapper,
      wrapperHeight,
      getRenderURL,
      getKey
    };
  }
};
</script>

<style scoped>
.waterfall-list {
  position: relative;
  overflow: hidden;
  width: 100%;
}

.waterfall-item {
  position: absolute;
  visibility: hidden;
  will-change: transform;
  transition: transform 0.3s ease;
}
</style>